#include <boost/test/unit_test.hpp>
 
#include "Vector.h"
#include "Matrix.h"
#include "Triangle.h"
#include "Ray.h"
#include "Plane.h"
#include "Vertex.h"


BOOST_AUTO_TEST_CASE(Vector_Operateurs)
{
    Math::Vector a(3.0f, 2.0f, 1.0f);
    // operator*
    Math::Vector b = a*3;
    BOOST_CHECK(b.x == 9);
    BOOST_CHECK(b.y == 6);
    BOOST_CHECK(b.z == 3);
    // operator==
    BOOST_CHECK(b == Math::Vector(9,6,3));
    // operator+/-
    BOOST_CHECK((a+b) == Math::Vector(12,8,4));
    BOOST_CHECK((b-a) == Math::Vector(6,4,2));
}

BOOST_AUTO_TEST_CASE(Vector_Fonctions)
{
    Math::Vector a(3.0f, 2.0f, 1.0f);
    Math::Vector b(4.0f, 5.0f, 6.0f);
    // dot
    BOOST_CHECK(a.dot(b) == 28);
    BOOST_CHECK(b.dot(a) == 28);
    // cross
    BOOST_CHECK(a.cross(b) == Math::Vector(7,-14,7));
}

BOOST_AUTO_TEST_CASE(Vector_Construction)
{
    Math::Vector *pV = new Math::Vector();
    delete pV;
}

BOOST_AUTO_TEST_CASE(Matrix_Multiplications){
    Math::Matrix A;
    Math::Matrix B;
    BOOST_CHECK(A==B);
    A = A+2;
    B = (B+(-1))*2;
    Math::Matrix C;
    C = C+(-16);
    BOOST_CHECK( (A*B) == C );
}

BOOST_AUTO_TEST_CASE(Plane_Intersection){
    
    Math::Plane T(Math::Vector(0,0,0),
                  Math::Vector(1,0,0));
    // devrait croiser T
    Math::Ray a(Math::Vector(0.5,0.5,1),
                Math::Vector(0,0,-1));
    // devrait croiser T, mais par derriere (donc ne 
    // pas le croiser pusiqu'on teste une demi-droite
    // et non une droite)
    Math::Ray a0(Math::Vector(0.5,0.5,-1),
                 Math::Vector(0,0,-1));
    // devrait etre parallele a T
    Math::Ray b(Math::Vector(0.5,0.5,1),
                Math::Vector(0,1,0));
    // devrait croiser P_T mais pas T
    Math::Ray c(Math::Vector(0.5,0.5,1),
                Math::Vector(1,1,-0.1));
    // devrait croiser P_T mais pas T
    Math::Ray d(Math::Vector(0.5,0.51,1),
                Math::Vector(0,0,-1));
    float k = 10000000;
    Math::Vector v(1,0,0);
    BOOST_CHECK( T.intersects(a,k,v) );
    BOOST_CHECK( !T.intersects(a0,k,v));
    BOOST_CHECK( !T.intersects(b,k,v) );
    BOOST_CHECK( !T.intersects(c,k,v) );
    BOOST_CHECK( !T.intersects(d,k,v) );
    
}

BOOST_AUTO_TEST_CASE(Vertex_Test){
    BOOST_CHECK( Math::Vertex::vectorFromVertices(Math::Vertex(4,5,6),Math::Vertex(8,12,16)) == Math::Vector(4,7,10));
}
